package com.github.yoojia.flow;

import com.parkingwang.lang.data.Config;

import java.util.List;
import java.util.Set;

/**
 * @author 2017 Yoojia Chen (yoojiachen@gmail.com)
 */
public interface Context {

    /**
     * 远程目标地址前缀标识符
     */
    String PREFIX_REMOTE_DESTINATION = "remote://";

    // 默认Topic

    String TOPIC_INPUT = "INPUTS";
    String TOPIC_OUTPUT = "OUTPUTS";
    String TOPIC_SWITCH = "SWITCHES";
    String TOPIC_SENSOR = "SENSORS";

    /**
     * 无指定目标
     */
    String ADDRESS_NONE = "*";

    String TOPIC_SYS_PREFIX = "#FLOW.SYS";
    /**
     * 没有任何响应内容
     */
    String TOPIC_SYS_NORESP = topicAppend(TOPIC_SYS_PREFIX, "NORESP");

    /**
     * 请求事件的处理超时
     */
    String TOPIC_SYS_TIMEOUT = topicAppend(TOPIC_SYS_PREFIX, "TIMEOUT");

    /**
     * 请求事件被过滤
     */
    String TOPIC_SYS_FILTERED = topicAppend(TOPIC_SYS_PREFIX, "FILTERED");

    /**
     * 请求事件没有目标处理设备
     */
    String TOPIC_SYS_NOT_FOUND = topicAppend(TOPIC_SYS_PREFIX, "NOTFOUND");

    /**
     * 请求事件被忽略
     */
    String TOPIC_SYS_SKIPPED = topicAppend(TOPIC_SYS_PREFIX, "SKIPPED");

    /**
     * 请求事件在处理中发生错误
     */
    String TOPIC_SYS_ERROR = topicAppend(TOPIC_SYS_PREFIX, "ERROR");


    /**
     * 获取下一个序列ID
     *
     * @return Long序列ID
     */
    long nextSequenceId();

    /**
     * 发送请求事件，等待返回响应事件
     *
     * @param request 请求事件
     * @return 响应事件
     */
    Event requestEvent(Event request);

    /**
     * 发送事件
     *
     * @param event Event
     */
    void publishEvent(Event event);

    /**
     * 按设备地址来查找设备对象
     *
     * @param address 设备地址
     * @return 匹配的设备对象。否则返回 null。
     */
    VirtualDevice findLocalDevice(String address);

    /**
     * 获取根配置对象
     *
     * @return Config
     */
    Config getGlobalConfig();

    /**
     * @return 本地设备的地址列表
     */
    Set<String> getDeviceAddresses();

    /**
     * @return 本地虚拟设备列表
     */
    List<VirtualDevice> getVirtualDevices();

    ////

    /**
     * 事件Topic追加下一级
     *
     * @param topic 原Topic
     * @param seg   新Topic的字段
     * @return Topic
     */
    static String topicAppend(String topic, String seg) {
        return topic + "/" + seg;
    }

}
